home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Jumpstart / Multimedia Microsoft Jumpstart Version 1.1a (Microsoft).BIN / develpmt / sdk / vfw11.win / vfwdk / palmap.c_ / palmap.bin
Encoding:
Text File  |  1993-11-19  |  13.5 KB  |  504 lines

  1. /****************************************************************************
  2.  *
  3.  *  PALMAP.C
  4.  *
  5.  *  Stream handler to map to a palette.
  6.  *
  7.  ***************************************************************************/
  8.  
  9. /**************************************************************************
  10.  *
  11.  *  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  12.  *  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  13.  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  14.  *  PURPOSE.
  15.  *
  16.  *  Copyright (c) 1992, 1993  Microsoft Corporation.  All Rights Reserved.
  17.  * 
  18.  **************************************************************************/
  19.  
  20. #include <windows.h>
  21. #include <windowsx.h>
  22. #include <mmsystem.h>
  23. #include <compman.h>
  24. #include <avifile.h>
  25. #include "dibmap.h"
  26. #include "palmap.h"
  27. #include "palmap.rc"
  28.  
  29. HINSTANCE    ghMod;
  30.  
  31. STDAPI AVIStreamMakePalette(PAVISTREAM pavi, LONG lSkip,
  32.                   HPALETTE FAR *lphpal,
  33.                   LPBYTE lp16to8,
  34.                   int nColors)
  35. {
  36.     LPHISTOGRAM lpHist = NULL;
  37.     LONG    l, lEnd;
  38.     LONG    lRet = AVIERR_OK;
  39.     PGETFRAME    pgf = NULL;
  40.  
  41.     if (!pavi || !lphpal || nColors < 2 || nColors > 256)
  42.     return ResultFromScode(AVIERR_BADPARAM);
  43.  
  44.     if (lSkip < 1)
  45.     lSkip = 1;
  46.  
  47.     lpHist = InitHistogram(NULL);
  48.     if (!lpHist)
  49.     return ResultFromScode(AVIERR_MEMORY);
  50.  
  51.     pgf = AVIStreamGetFrameOpen(pavi, NULL);
  52.     
  53.     l = AVIStreamStart(pavi);
  54.     lEnd = l + AVIStreamLength(pavi);
  55.     for (l = AVIStreamStart(pavi), lEnd = l + AVIStreamLength(pavi);
  56.         l < lEnd;
  57.         l += lSkip) {
  58.     LPBITMAPINFOHEADER lpbi;
  59.  
  60.     lpbi = AVIStreamGetFrame(pgf, l);
  61.  
  62.     if (!lpbi) {
  63.         lRet = AVIERR_INTERNAL;
  64.         goto error;
  65.     }
  66.     
  67.     DibHistogram(lpbi, NULL, 0, 0, -1, -1, lpHist);
  68.     }
  69.  
  70.     *lphpal = HistogramPalette(lpHist, lp16to8, nColors);
  71.  
  72.     if (!*lphpal)
  73.     lRet = AVIERR_MEMORY;
  74.  
  75. error:
  76.     if (pgf)
  77.     AVIStreamGetFrameClose(pgf);
  78.     
  79.     if (lpHist)
  80.     FreeHistogram(lpHist);
  81.  
  82.     return ResultFromScode(lRet);
  83. }
  84.  
  85.  
  86.  
  87. typedef struct {
  88.     IAVIStreamVtbl FAR *    lpVtbl;
  89.  
  90.     ULONG            ulRefCount;
  91.  
  92.     //
  93.     // instance data
  94.     //
  95.     PAVISTREAM        pavi;
  96.     PGETFRAME        pgf;
  97.     AVISTREAMINFO   sinfo;    
  98.     HPALETTE        hpal;
  99.     LPBYTE        lp16to8;
  100.     LONG        lLastFrame;
  101.     HANDLE        hdibLast;
  102. } PALMAPSTREAM, FAR*PPALMAPSTREAM;
  103.  
  104. ///////////////////////////////////////////////////////////////////////////
  105. ///////////////////////////////////////////////////////////////////////////
  106.  
  107. HRESULT STDMETHODCALLTYPE PalMapStreamQueryInterface(PAVISTREAM ps, REFIID riid, LPVOID FAR* ppvObj);
  108. HRESULT STDMETHODCALLTYPE PalMapStreamCreate       (PAVISTREAM ps, LONG lParam1, LONG lParam2);
  109. ULONG   STDMETHODCALLTYPE PalMapStreamAddRef       (PAVISTREAM ps);
  110. ULONG   STDMETHODCALLTYPE PalMapStreamRelease      (PAVISTREAM ps);
  111. HRESULT STDMETHODCALLTYPE PalMapStreamInfo         (PAVISTREAM ps, AVISTREAMINFO FAR * psi, LONG lSize);
  112. LONG    STDMETHODCALLTYPE PalMapStreamFindKeyFrame (PAVISTREAM ps, LONG lPos, LONG lFlags);
  113. HRESULT STDMETHODCALLTYPE PalMapStreamReadFormat   (PAVISTREAM ps, LONG lPos, LPVOID lpFormat, LONG FAR *lpcbFormat);
  114. HRESULT STDMETHODCALLTYPE PalMapStreamSetFormat    (PAVISTREAM ps, LONG lPos, LPVOID lpFormat, LONG cbFormat);
  115. HRESULT STDMETHODCALLTYPE PalMapStreamRead         (PAVISTREAM ps, LONG lStart, LONG lSamples, LPVOID lpBuffer, LONG cbBuffer, LONG FAR * plBytes,LONG FAR * plSamples);
  116. HRESULT STDMETHODCALLTYPE PalMapStreamWrite        (PAVISTREAM ps, LONG lStart, LONG lSamples, LPVOID lpBuffer, LONG cbBuffer, DWORD dwFlags, LONG FAR *plSampWritten, LONG FAR *plBytesWritten);
  117. HRESULT STDMETHODCALLTYPE PalMapStreamDelete       (PAVISTREAM ps, LONG lStart, LONG lSamples);
  118. HRESULT STDMETHODCALLTYPE PalMapStreamReadData     (PAVISTREAM ps, DWORD fcc, LPVOID lp,LONG FAR *lpcb);
  119. HRESULT STDMETHODCALLTYPE PalMapStreamWriteData    (PAVISTREAM ps, DWORD fcc, LPVOID lp,LONG cb);
  120. HRESULT STDMETHODCALLTYPE PalMapStreamReserved     (PAVISTREAM ps);
  121.  
  122. IAVIStreamVtbl PalMapStreamHandler = {
  123.     PalMapStreamQueryInterface,
  124.     PalMapStreamAddRef,
  125.     PalMapStreamRelease,
  126.     PalMapStreamCreate,
  127.     PalMapStreamInfo,
  128.     PalMapStreamFindKeyFrame,
  129.     PalMapStreamReadFormat,
  130.     PalMapStreamSetFormat,
  131.     PalMapStreamRead,
  132.     PalMapStreamWrite,
  133.     PalMapStreamDelete,
  134.     PalMapStreamReadData,
  135.     PalMapStreamWriteData,
  136.     PalMapStreamReserved,
  137.     PalMapStreamReserved,
  138.     PalMapStreamReserved,
  139.     PalMapStreamReserved,
  140.     PalMapStreamReserved
  141. };
  142.  
  143. STDAPI AVICreateMappedStream(PAVISTREAM FAR *ppsMapped,
  144.                    PAVISTREAM ps,
  145.                    int nColors)
  146. {
  147.     PPALMAPSTREAM   pavi;
  148.     HRESULT        hr;
  149.  
  150.     *ppsMapped = 0;
  151.     
  152.     pavi = (PPALMAPSTREAM) GlobalAllocPtr(GHND, sizeof(PALMAPSTREAM));
  153.     if (pavi == NULL)
  154.         return ResultFromScode(AVIERR_MEMORY);
  155.  
  156.     pavi->lpVtbl = &PalMapStreamHandler;
  157.     
  158.     hr = (pavi->lpVtbl->Create)((PAVISTREAM) pavi, (LONG) ps, nColors);
  159.  
  160.     if (hr != NOERROR) {
  161.     (pavi->lpVtbl->Release)((PAVISTREAM) pavi);
  162.     return hr;
  163.     }
  164.     
  165.     *ppsMapped = (PAVISTREAM) pavi;
  166.  
  167.     return AVIERR_OK;
  168.  
  169.  
  170. }
  171.  
  172. ///////////////////////////////////////////////////////////////////////////
  173. //
  174. //  PalMapStreamOpen()
  175. //
  176. //  open a single stream of a particular type from a AVI file.
  177. //
  178. //  params:
  179. //      szFile      - PAVISTREAM
  180. //      fccType     - must be streamtypeVIDEO
  181. //      lParam        - nColors
  182. //
  183. //  returns:
  184. //      a PAVISTREAM for the specifed stream or NULL.
  185. //
  186. ///////////////////////////////////////////////////////////////////////////
  187.  
  188. HRESULT STDMETHODCALLTYPE PalMapStreamCreate(PAVISTREAM ps, LONG lParam1, LONG lParam2)
  189. {
  190.     PPALMAPSTREAM    pavi = (PPALMAPSTREAM) ps;
  191.     char        achTemp[128];
  192.     char        achTemplate[64];
  193.  
  194.     LONG        lRet = AVIERR_OK;
  195.  
  196.     pavi->ulRefCount = 1;
  197.     
  198.     if (AVIStreamAddRef((PAVISTREAM) lParam1) != AVIERR_OK)
  199.     return ResultFromScode(AVIERR_FILEOPEN);
  200.  
  201.     pavi->pavi = (PAVISTREAM) lParam1;
  202.     
  203.     AVIStreamInfo(pavi->pavi, &pavi->sinfo, sizeof(pavi->sinfo));
  204.  
  205.     if (pavi->sinfo.fccType != streamtypeVIDEO) {
  206.     lRet = AVIERR_INTERNAL;
  207.     goto error;
  208.     }
  209.  
  210.     pavi->pgf = AVIStreamGetFrameOpen(pavi->pavi, NULL);
  211.  
  212.     if (!pavi->pgf) {
  213.     lRet = AVIERR_INTERNAL;
  214.     goto error;
  215.     }
  216.  
  217.     pavi->sinfo.fccHandler = 0;
  218.  
  219.     // Fix up stream name
  220.     LoadString(ghMod, IDS_STREAMNAME, achTemplate, sizeof(achTemplate));
  221.     wsprintf(achTemp, achTemplate, pavi->sinfo.szName, lParam2);
  222.     lstrcpyn(pavi->sinfo.szName, achTemp, sizeof(pavi->sinfo.szName));
  223.     pavi->sinfo.szName[sizeof(pavi->sinfo.szName) - 1] = '\0';
  224.  
  225.     // default to 256 colors
  226.     if (lParam2 < 2 || lParam2 > 256)
  227.     lParam2 = 256;
  228.  
  229.     pavi->lp16to8 = GlobalAllocPtr(GMEM_MOVEABLE, 32768L);
  230.     if (!pavi->lp16to8) {
  231.     lRet = AVIERR_MEMORY;
  232.     goto error;
  233.     }
  234.     
  235.     lRet = GetScode(AVIStreamMakePalette(pavi->pavi,
  236.                 AVIStreamLength(pavi->pavi) / 30,
  237.                 &pavi->hpal, pavi->lp16to8,
  238.                 (int) lParam2));
  239.  
  240.     pavi->lLastFrame = -1;
  241.     
  242. error:
  243.     return ResultFromScode(lRet);
  244. }
  245.  
  246. ///////////////////////////////////////////////////////////////////////////
  247. //
  248. //  PalMapStreamQueryInterface()
  249. //
  250. //      let other people know what interfaces we support
  251. //
  252. ///////////////////////////////////////////////////////////////////////////
  253. HRESULT STDMETHODCALLTYPE PalMapStreamQueryInterface(PAVISTREAM ps, REFIID riid, LPVOID FAR* ppvObj)
  254. {
  255.     PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  256.     
  257.     if (IsEqualIID(riid, &IID_IUnknown))
  258.         *ppvObj = ps;
  259.     else if (IsEqualIID(riid, &IID_IAVIStream))
  260.         *ppvObj = ps;
  261.     else
  262.         return ResultFromScode(E_NOINTERFACE);
  263.     
  264.     pavi->ulRefCount++;
  265.     return NOERROR;
  266. }
  267.  
  268. ///////////////////////////////////////////////////////////////////////////
  269. //
  270. //  PalMapStreamAddRef()
  271. //
  272. //      increase the reference count of the stream
  273. //
  274. ///////////////////////////////////////////////////////////////////////////
  275.  
  276. ULONG STDMETHODCALLTYPE PalMapStreamAddRef(PAVISTREAM ps)
  277. {
  278.     PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  279.  
  280.     return ++pavi->ulRefCount;
  281. }
  282.  
  283. ///////////////////////////////////////////////////////////////////////////
  284. //
  285. //  PalMapStreamRelease()
  286. //
  287. //      close a PalMapStream stream
  288. //
  289. ///////////////////////////////////////////////////////////////////////////
  290.  
  291. ULONG STDMETHODCALLTYPE PalMapStreamRelease(PAVISTREAM ps)
  292. {
  293.     PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  294.  
  295.     if (!pavi)
  296.     return 0;
  297.     
  298.     if (--pavi->ulRefCount)
  299.     return pavi->ulRefCount;
  300.  
  301.     if (pavi->pgf)
  302.     AVIStreamGetFrameClose(pavi->pgf);
  303.     pavi->pgf = 0;
  304.     
  305.     if (pavi->pavi)
  306.     AVIStreamClose(pavi->pavi);
  307.     pavi->pavi = 0;
  308.  
  309.     if (pavi->lp16to8) {
  310.     GlobalFreePtr(pavi->lp16to8);
  311.     pavi->lp16to8 = 0;
  312.     }
  313.  
  314.     if (pavi->hpal) {
  315.     DeleteObject(pavi->hpal);
  316.     pavi->hpal = 0;
  317.     }
  318.     
  319.     if (pavi->hdibLast) {
  320.     GlobalFree(pavi->hdibLast);
  321.     pavi->hdibLast = 0;
  322.     }
  323.     
  324.     GlobalFreePtr(pavi);
  325.     
  326.     return 0;
  327. }
  328.  
  329. ///////////////////////////////////////////////////////////////////////////
  330. ///////////////////////////////////////////////////////////////////////////
  331.  
  332. HRESULT STDMETHODCALLTYPE PalMapStreamReadFormat(PAVISTREAM ps, LONG lPos, LPVOID lpFormat, LONG FAR *lpcbFormat)
  333. {
  334.     PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  335.     LPBITMAPINFOHEADER  lpbi;
  336.     LONG        lSize;
  337.     
  338.     PalMapStreamRead(ps, lPos, 1, NULL, 0, NULL, NULL);
  339.  
  340.     if (pavi->hdibLast == 0)
  341.     return ResultFromScode(AVIERR_INTERNAL);
  342.     
  343.     lpbi = (LPBITMAPINFOHEADER) GlobalLock(pavi->hdibLast);    
  344.     
  345.     lSize = lpbi->biSize + lpbi->biClrUsed * sizeof(RGBQUAD); 
  346.  
  347.     if (lpFormat)
  348.     hmemcpy(lpFormat, lpbi, min(*lpcbFormat, lSize));
  349.  
  350.     *lpcbFormat = lSize;
  351.     
  352.     return 0;
  353. }
  354.  
  355. LONG STDMETHODCALLTYPE PalMapStreamFindKeyFrame(PAVISTREAM ps, LONG lPos, LONG lFlags)
  356. {
  357.     PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  358.  
  359.     return lPos;    
  360. }
  361.  
  362.  
  363. ///////////////////////////////////////////////////////////////////////////
  364. ///////////////////////////////////////////////////////////////////////////
  365.  
  366. HRESULT STDMETHODCALLTYPE PalMapStreamInfo(PAVISTREAM ps, AVISTREAMINFO FAR * psi, LONG lSize)
  367. {
  368.     PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  369.  
  370.     if (psi)
  371.     hmemcpy(psi, &pavi->sinfo, min(lSize, sizeof(pavi->sinfo)));
  372.     
  373.     return 0;
  374. }
  375.  
  376.  
  377. ///////////////////////////////////////////////////////////////////////////
  378. ///////////////////////////////////////////////////////////////////////////
  379.  
  380. HRESULT STDMETHODCALLTYPE PalMapStreamRead(PAVISTREAM   ps,
  381.                  LONG       lStart,
  382.                  LONG       lSamples,
  383.                  LPVOID     lpBuffer,
  384.                  LONG       cbBuffer,
  385.                  LONG FAR * plBytes,
  386.                  LONG FAR * plSamples)
  387. {
  388.     PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  389.  
  390.     LPBITMAPINFOHEADER  lpbi;
  391.     LPVOID        lp;
  392.  
  393.     if (lStart != pavi->lLastFrame) {
  394.     pavi->lLastFrame = -1;
  395.     lpbi = AVIStreamGetFrame(pavi->pgf, lStart);
  396.     
  397.     if (!lpbi)
  398.         goto ReadNothing;
  399.  
  400.     if (pavi->hdibLast) {
  401.         GlobalFree(pavi->hdibLast);
  402.         pavi->hdibLast = 0;
  403.     }
  404.  
  405.     pavi->hdibLast = DibReduce(lpbi, NULL, pavi->hpal, pavi->lp16to8);
  406.     pavi->lLastFrame = lStart;
  407.     }
  408.  
  409.     lpbi = (LPBITMAPINFOHEADER) GlobalLock(pavi->hdibLast);    
  410.     //
  411.     // a NULL buffer means return the size buffer needed to read
  412.     // the given sample.
  413.     //
  414.     lp = (LPBYTE) lpbi + lpbi->biSize + lpbi->biClrUsed * sizeof(RGBQUAD);
  415.     
  416.     if (plBytes)
  417.     *plBytes = lpbi->biSizeImage;
  418.         
  419.     if (plSamples)
  420.     *plSamples = 1;
  421.  
  422.     if (lpBuffer) {
  423.     if (cbBuffer >= (LONG) lpbi->biSizeImage)
  424.         hmemcpy(lpBuffer, lp, lpbi->biSizeImage);
  425.     else
  426.         return ResultFromScode(AVIERR_BUFFERTOOSMALL);
  427.     }
  428.     
  429.     return 0;
  430.     
  431. ReadNothing:
  432.     if (plBytes)
  433.     *plBytes = 0;
  434.  
  435.     if (plSamples)
  436.     *plSamples = 0;
  437.  
  438.     return ResultFromScode(AVIERR_BUFFERTOOSMALL);
  439. }
  440.  
  441.  
  442.  
  443. //
  444. //
  445. //   Extra unimplemented functions.....
  446. //
  447. //
  448. //
  449. HRESULT STDMETHODCALLTYPE PalMapStreamReadData     (PAVISTREAM ps, DWORD fcc, LPVOID lp, LONG FAR *lpcb)
  450. {
  451.     PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  452.     return ResultFromScode(AVIERR_UNSUPPORTED);
  453. }
  454.  
  455. HRESULT STDMETHODCALLTYPE PalMapStreamSetFormat    (PAVISTREAM ps, LONG lPos, LPVOID lpFormat, LONG cbFormat)
  456. {
  457.     PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  458.     return ResultFromScode(AVIERR_UNSUPPORTED);
  459. }
  460.  
  461. HRESULT STDMETHODCALLTYPE PalMapStreamWriteData    (PAVISTREAM ps, DWORD fcc, LPVOID lp, LONG cb)
  462. {
  463.     PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  464.     return ResultFromScode(AVIERR_UNSUPPORTED);
  465. }
  466.  
  467. HRESULT STDMETHODCALLTYPE PalMapStreamWrite        (PAVISTREAM ps, LONG lStart, LONG lSamples, LPVOID lpBuffer, LONG cbBuffer, DWORD dwFlags, LONG FAR *plSampWritten, LONG FAR *plBytesWritten)
  468. {
  469.     PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  470.     return ResultFromScode(AVIERR_UNSUPPORTED);
  471. }
  472.  
  473. HRESULT STDMETHODCALLTYPE PalMapStreamDelete       (PAVISTREAM ps, LONG lStart, LONG lSamples)
  474. {
  475.     PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  476.     return ResultFromScode(AVIERR_UNSUPPORTED);
  477. }
  478.  
  479. HRESULT STDMETHODCALLTYPE PalMapStreamReserved     (PAVISTREAM ps)
  480. {
  481.     PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  482.     return ResultFromScode(AVIERR_UNSUPPORTED);
  483. }
  484.  
  485.  
  486.  
  487. EXTERN_C int CALLBACK WEP(BOOL fSystemExit)
  488. {
  489.     return TRUE;
  490. }
  491.  
  492.  
  493. EXTERN_C int CALLBACK LibMain(
  494.         HINSTANCE       hInstance,
  495.         UINT            uDataSeg,
  496.         UINT            cbHeapSize,
  497.         LPCSTR          pszCmdLine)
  498. {
  499.     // save our module handle
  500.     ghMod = hInstance;
  501.     return TRUE;
  502. }
  503.  
  504.